﻿using System;
using System.Collections;
using System.Text;
using System.Net;
using System.IO;
using ComponentAce.Compression.Libs.zlib;
using System.Collections.Generic;
using com.lover.common.http;

namespace com.lover.common
{
    public class TransferMgr
    {
        public static string doGet(string url, ref List<Cookie> cookies)
        {
            string retstr = "";
            // get response
            HttpResult resp = doGetPure( url, ref cookies);

            if (resp == null || resp.StatusCode == 0)
            {
                // 表示网断了
                retstr = "code:-1";
                return retstr;
            }
            else if (resp.StatusCode != 200 && resp.StatusCode != 304)
            {
                retstr = "code:" + (int)resp.StatusCode;
                return retstr;
            }

            Stream instream = resp.ContentStream;
            
            MemoryStream outst = new MemoryStream();
            ZOutputStream zoutstream = new ZOutputStream(outst);
            try
            {
                CopyStream(instream, zoutstream);
                outst.Position = 0;
                StreamReader reader = new StreamReader(outst);
                retstr = reader.ReadToEnd();
                // remove the first 3 utf-8 BOM char (EF BB BF)
                int index = retstr.IndexOf("<results>");
                if (index < 0) retstr = "";
                else retstr = retstr.Substring(index);
            }
            finally
            {
                instream.Close();
                outst.Close();
                zoutstream.Close();
            }
            return retstr;
        }
        public static string doPost(string url, string data, ref List<Cookie> cookies)
        {
            string retstr = "";
            // get response
            HttpResult resp = doPostPure(url, data, ref cookies);

            if (resp == null || resp.StatusCode == 0)
            {
                // 表示网断了
                retstr = "code:-1";
                return retstr;
            }
            else if (resp.StatusCode != 200 && resp.StatusCode != 304)
            {
                retstr = "code:" + (int)resp.StatusCode;
                return retstr;
            }

            Stream instream = resp.ContentStream;

            MemoryStream outst = new MemoryStream();
            ZOutputStream zoutstream = new ZOutputStream(outst);
            try
            {
                CopyStream(instream, zoutstream);
                outst.Position = 0;
                StreamReader reader = new StreamReader(outst);
                retstr = reader.ReadToEnd();
                // remove the first 3 utf-8 BOM char (EF BB BF)
                int index = retstr.IndexOf("<results>");
                if (index < 0) retstr = "";
                else retstr = retstr.Substring(index);
            }
            finally
            {
                instream.Close();
                outst.Close();
                zoutstream.Close();
            }
            return retstr;
        }
        public static void CopyStream(System.IO.Stream input, System.IO.Stream output)
        {
            byte[] buffer = new byte[2000];
            int len;
            while ((len = input.Read(buffer, 0, 2000)) > 0)
            {
                output.Write(buffer, 0, len);
            }
            output.Flush();
        }
        public static HttpResult doGetPure(string url, ref List<Cookie> cookies, 
            string referer = "", Dictionary<string, string> headers = null)
        {
            try
            {
                if (!url.StartsWith("http://") && !url.StartsWith("https://"))
                {
                    url = "http://" + url;
                }
                HttpSocket sock = new HttpSocket();
                sock.Method = "GET";
                sock.Url = url;
                if (referer != null && referer != "") sock.Referer = referer;
                if (headers != null && headers.Count > 0)
                {
                    IEnumerator<string> header_enumer = headers.Keys.GetEnumerator();
                    while (header_enumer.MoveNext())
                    {
                        string key = header_enumer.Current;
                        sock.addExtraHeader(key, headers[key]);
                    }
                }
                sock.setCookies(cookies);

                // get response
                HttpResult result = sock.execute();
                if (cookies != null)
                {
                    List<Cookie> resp_cookies = result.getCookies();
                    CommonUtils.updateCookies(ref cookies, ref resp_cookies);
                }
                return result;
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(String.Format("ERROR:{0}::{1}", ex.Message, ex.StackTrace));
            }

            return null;
        }

        public static HttpResult doPostPure(string url, string data, ref List<Cookie> cookies, 
            string referer = "", Dictionary<string, string> headers = null)
        {
            try
            {
                if (!url.StartsWith("http://") && !url.StartsWith("https://"))
                {
                    url = "http://" + url;
                }
                HttpSocket sock = new HttpSocket();
                sock.Method = "POST";
                sock.Url = url;
                if (referer != null && referer != "") sock.Referer = referer;
                if (headers != null && headers.Count > 0)
                {
                    IEnumerator<string> header_enumer = headers.Keys.GetEnumerator();
                    while (header_enumer.MoveNext())
                    {
                        string key = header_enumer.Current;
                        sock.addExtraHeader(key, headers[key]);
                    }
                }
                sock.setCookies(cookies);
                sock.Data = data;

                // get response
                HttpResult result = sock.execute();
                if (cookies != null)
                {
                    List<Cookie> resp_cookies = result.getCookies();
                    CommonUtils.updateCookies(ref cookies, ref resp_cookies);
                }
                return result;
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(String.Format("ERROR:{0}::{1}", ex.Message, ex.StackTrace));
            }

            return null;
        }
    }
}
